#include "IntegralHistSet.h"


//////////////////////////////////////////////////////////////////
// GhostSet Object												//
//////////////////////////////////////////////////////////////////

// Constructor for ghost set without arguments.
GhostSet::GhostSet()
{
	_n = 0;
	_pos = 0;
	_neg = 0;
	_head = NULL;
	_tail = NULL;
}

// Constructor for ghost set from set of integral histograms.
GhostSet::GhostSet(IntegralHistSet *i_set)
{
	// Copy number of images across
	_n = i_set->_n;
	_pos = i_set->_pos;
	_neg = i_set->_neg;

	// Check if there is stuff to copy across
	if(i_set->_head)
	{
		// Initialise the beginning of the list with the correct image
		_head = new IntegralHistNode;
		_head->_label = i_set->_head->_label;
		if(i_set->_head->_hist)
			_head->_hist = i_set->_head->_hist;
		_head->next = NULL;
		_head->previous = NULL;
		_tail = _head;

		// Traverse the list and copy everything across, except 
		// the actual integral histograms.
		IntegralHistNode* temp = i_set->_head;
		while(temp->next)
		{
			_tail->next = new IntegralHistNode;
			_tail->next->_label = temp->next->_label;
			_tail->next->_hist = temp->next->_hist;
			_tail->next->next = NULL;
			_tail->next->previous = _tail;
			_tail = _tail->next;
			temp = temp->next;
		}
	}
	else
	{
		_head = NULL;
		_tail = NULL;
	}
}

// Copy constructor for ghost set.
GhostSet::GhostSet(const GhostSet& init)
{
	// Copy number of images across
	_n = init._n;
	_pos = init._pos;
	_neg = init._neg;

	// Check if we need to copy stuff across
	if(init._head)
	{
		// Initialise the beginning of the list with the correct image
		_head = new IntegralHistNode;
		_head->_label = init._head->_label;
		if(init._head->_hist)
			_head->_hist = init._head->_hist;
		_head->next = NULL;
		_head->previous = NULL;
		_tail = _head;

		// Traverse the list and copy everything across, except 
		// the actual integral histograms.
		IntegralHistNode* temp = init._head;
		while(temp->next)
		{
			_tail->next = new IntegralHistNode;
			_tail->next->_label = temp->next->_label;
			_tail->next->_hist = temp->next->_hist;
			_tail->next->previous = _tail;
			_tail = _tail->next;
			temp = temp->next;
		}
		_tail->next = NULL;
	}
	else
	{
		_head = NULL;
		_tail = NULL;
	}
}

// Destructor for ghost set. Same as integral histogram set, 
// except that it does not delete memory occupied by integral 
// histograms.
GhostSet::~GhostSet()
{
	// Loop while we are not at the head node
	if(_tail)
		while(_tail->previous)
		{
			// Jump back one
			_tail = _tail->previous;
			// Delete the node at the end of the list
			if(_tail->next)
				delete _tail->next;
		}

	// Delete the head node
	if(_head)
	{
		delete _head;
	}
}

//
GhostSet& GhostSet::operator=(const GhostSet& r_set)
{
	// Check for self assignment. This is very important!
	if(this == &r_set)
		return *this;

	// Release memory by executing destructor code.
	if(_tail)
		while(_tail->previous)
		{
			_tail = _tail->previous;
			if(_tail->next)
				delete _tail->next;
		}

	if(_head)
	{
		delete _head;
	}

	// Copy across data from value on right using copy constructor
	// code.
	_n = r_set._n;
	_pos = r_set._pos;
	_neg = r_set._neg;

	if(r_set._head)
	{
		// Initialise the beginning of the list with the correct image
		_head = new IntegralHistNode;
		_head->_label = r_set._head->_label;
		if(r_set._head->_hist)
			_head->_hist = r_set._head->_hist;
		_head->next = NULL;
		_head->previous = NULL;
		_tail = _head;

		IntegralHistNode* temp = r_set._head;
		while(temp->next)
		{
			_tail->next = new IntegralHistNode;
			_tail->next->_label = temp->next->_label;
			_tail->next->_hist = temp->next->_hist;
			_tail->next->previous = _tail;
			_tail = _tail->next;
			temp = temp->next;
		}
		_tail->next = NULL;
	}
	else
	{
		_head = NULL;
		_tail = NULL;
	}

	// Return a reference to this object
	return *this;
}
